﻿using DGZImp.Core.Extensions;
using DGZImp.Core.Services;
using DGZImp.Core.Utilities;
using DGZImp.MdsProject.Base;
using DGZImp.MdsProject.Devices.Base;
using DGZImp.MdsProject.Devices.Helper;
using DGZImp.MdsProject.Devices.Models;
using DGZImp.MdsProject.Helper;
using Newtonsoft.Json;
using Nomad.Iot;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;

namespace DGZImp.MdsProject.Devices
{
    /// <summary>
    /// 镭神Agv
    /// </summary>
    public class LsAgv : BaseDevice
    {
        public AgvData Data { get; set; }

        public RealDeviceTypeEmun Type { get; set; }

        public string Code { get; set; }

        public LsAgv(string id, string name, IIotServe serve, RealDeviceTypeEmun type, string code) : base(id, name, serve)
        {
            Type = type;
            serve.OnHttpDataReceive += DataReceiveHandler;
            Data = new AgvData();
            Code = code ?? name;
        }

        public void DataReceiveHandler(object sender, string data)
        {
            try
            {
                var obj = JsonConvert.DeserializeObject<HttpRes<List<AgvData>>>(data);
                if (obj.Code == 0)
                {
                    var tmp = obj.Data.Where(x => x.AgvName == Code).FirstOrDefault();
                    if (tmp != null)
                    {
                        tmp.RefreshTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                        Data = tmp;
                    }
                    else
                    {
                        Data = new AgvData();
                    }
                }
                else
                {
                    SysLogger.LogError($"AGV数据响应失败：{data}");
                    Data = new AgvData();
                }
            }
            catch (Exception e)
            {
                SysLogger.LogError(e, $"AGV数据解析失败：{data}");
                Data = new AgvData();
            }

        }

        public async Task<OperateResult> SendNormalTaskAsync(AgvCommandEmun command, int taskNo, string start = "", string end = "", bool isCurrent = false)
        {

            var res = new OperateResult();

            var data = LsAgvHelper.GenerateTaskData(new CreateLsAgvTaskDto
            {
                Command = command,
                TaskNo = taskNo,
                Start = start,
                End = end,
                DeviceType = Type,
                DeviceIp = isCurrent ? Data.AgvIp : ""
            });

            var path = command == AgvCommandEmun.取消任务 ? "services/taskOperation" : "services/genAgvSchedulingTask";
            SysLogger.LogDebug($"发送LSAGV：{JsonConvert.SerializeObject(data)}");
            long startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var result = await ((HttpServe)Serve).SendRequestAsync(new HttpRequestModel
            {
                Path = $"services/taskOperation",
                Method = "POST",
                Body = JsonConvert.SerializeObject(data),
            });
            long endTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            long durationMilliseconds = endTime - startTime;
            SysLogger.LogDebug($"发送LSAGV，响应时间：{durationMilliseconds}ms，响应内容：{result}");
            try
            {
                if (result.IsNullOrEmpty()) throw new Exception("AGV响应为空");
                var obj = JsonConvert.DeserializeObject<HttpRes<object>>(result);
                if (obj.Code == 0)
                {
                    res.IsSuccess = true;
                    res.Message = "指令下发成功";
                }
                else
                {
                    res.Message = $"下发失败，错误：{obj.Message}";
                }
            }
            catch (Exception e)
            {
                res.Message = $"下发失败，错误：{e.Message}";
            }
            return res;

        }

        [MdsAction("移动任务", "发送一个AGV移动任务")]
        public async Task<OperateResult> SendMoveTaskAsync([MdsParameter("目标点")] string end)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(AgvCommandEmun.移动任务, taskNo, "", end, true);
        }

        [MdsAction("取放货任务", "发送一个AGV取放货任务")]
        public async Task<OperateResult> SendTaskAsync([MdsParameter("起始点")] string start, [MdsParameter("目标点")] string end)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(AgvCommandEmun.取放货任务, taskNo, start, end, true);
        }

        [MdsAction("取货任务", "发送一个AGV取货任务")]
        public async Task<OperateResult> SendGetTaskAsync([MdsParameter("起始点")] string start)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(AgvCommandEmun.取货任务, taskNo, start, "", true);
        }

        [MdsAction("放货任务", "发送一个AGV放货任务")]
        public async Task<OperateResult> SendPutTaskAsync([MdsParameter("目标点")] string end)
        {
            var taskNo = SimpleSnowId.GenerateId();
            return await SendNormalTaskAsync(AgvCommandEmun.放货任务, taskNo, "", end, true);
        }

        [MdsAction("取消任务", "取消AGV任务")]
        public async Task<OperateResult> ClearTaskAsync([MdsParameter("任务号")] int taskNo)
        {
            return await SendNormalTaskAsync(AgvCommandEmun.取消任务, taskNo);
        }

        [MdsAction("继续任务", "AGV执行任务中等待指令继续进行时发送")]
        public async Task<OperateResult> SendContinueTaskAsync([MdsParameter("响应类型")] LsAgvControlTypeEnum type = LsAgvControlTypeEnum.点控制响应)
        {
            var res = new OperateResult();
            var req = new
            {
                reqCode = SimpleSnowId.GenerateId(),
                type = 9,
                deviceid = Data.AgvIp,
                operation_type = (int)type,
                operation_result = 1
            };
            SysLogger.LogDebug($"发送LSAGV：{JsonConvert.SerializeObject(req)}");
            long startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var result = await ((HttpServe)Serve).SendRequestAsync(new HttpRequestModel
            {
                Path = $"services/externalControlFeedback",
                Method = "POST",
                Body = JsonConvert.SerializeObject(req),
            });
            long endTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            long durationMilliseconds = endTime - startTime;
            SysLogger.LogDebug($"发送LSAGV，响应时间：{durationMilliseconds}ms，响应内容：{result}");
            try
            {
                if (result.IsNullOrEmpty()) throw new Exception("AGV响应为空");
                var obj = JsonConvert.DeserializeObject<HttpRes<object>>(result);
                if (obj.Code == 0)
                {
                    res.IsSuccess = true;
                    res.Message = "指令下发成功";
                }
                else
                {
                    res.Message = $"下发失败，错误：{obj.Message}";
                }
            }
            catch (Exception e)
            {
                res.Message = $"下发失败，错误：{e.Message}";
            }
            return res;
        }
    }

    public class HttpRes<T>
    {
        public int ResCode { get; set; }
        public int Code { get; set; }
        public string Message { get; set; }
        public T Data { get; set; }
        public int Type { get; set; }
    }

    public class HttpReq<T>
    {
        public int reqCode { get; set; }
        public int type { get; set; }
        public T data { get; set; }
    }

    public class addTaskData
    {
        public keyData key { get; set; }
        public List<valueDataItem> value { get; set; } = new List<valueDataItem>();
    }
    public class keyData
    {
        public bool ischain { get; set; }
        public bool custom_focal { get; set; }
    }
    public class valueDataItem
    {
        public string taskname { get; set; }
        public string task_type { get; set; }
        public string device_type { get; set; }
        public int index { get; set; }
        public int priority { get; set; } = 0;
        public string getlocation { get; set; }
        public string putlocation { get; set; }
        public string deslocation { get; set; }
        public string deviceid { get; set; }
    }

    public class modifyTaskData
    {
        public string taskname { get; set; }
        public int action { get; set; }
    }

    public class AgvData
    {
        [Description("01.车辆名称")]
        public string AgvName { get; set; }

        [Description("02.车辆IP")]
        public string AgvIp { get; set; }

        [Description("03.手动1/自动2")]
        public int AgvMode { get; set; }

        [Description("04.电量")]
        public int Battery { get; set; }

        [Description("05.载货状态")]
        public bool Stage { get; set; }

        [Description("06.运行状态")]
        public int HandleState { get; set; }

        [Description("07.任务号")]
        public string TaskName { get; set; }

        [Description("08.报警触发")]
        public bool AlarmTrigger { get; set; }

        [Description("09.X坐标")]
        public double PosX { get; set; }

        [Description("10.Y坐标")]
        public double PosY { get; set; }

        [Description("11.角度")]
        public double Yaw { get; set; }

        [Description("99.刷新时间")]
        public string RefreshTime { get; set; }
    }
}
